package com.xjoyt.pay.gateway.dao.impl;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.Predicate;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;

import com.xjoyt.pay.abstracts.AbstractDao;
import com.xjoyt.pay.dto.PageParam;
import com.xjoyt.pay.dto.PageResult;
import com.xjoyt.pay.gateway.dao.CallbackLogRepositoryCustom;
import com.xjoyt.pay.gateway.params.CallbackLogParam;
import com.xjoyt.pay.gateway.po.CallbackLog;
import com.xjoyt.pay.gateway.repository.CallbackLogRepository;

public class CallbackLogRepositoryImpl extends AbstractDao implements CallbackLogRepositoryCustom {

	@Autowired
	private CallbackLogRepository repository;

	@Override
	public PageResult<CallbackLog> loadPage(PageParam<CallbackLogParam> param) {
		Pageable pageable = getPageable(param);
		Specification<CallbackLog> spec = getSpecification(param.query);
		Page<CallbackLog> pageReuslt = repository.findAll(spec, pageable);
		return new PageResult<>(pageReuslt.getTotalElements(), pageReuslt.getContent());
	}

	private Specification<CallbackLog> getSpecification(CallbackLogParam param) {
		Specification<CallbackLog> spec = (root, query, cb) -> {
			if (param == null) {
				return null;
			}
			List<Predicate> list = new ArrayList<>();

			if (StringUtils.isNotBlank(param.distributorId)) {
				list.add(cb.equal(root.get("distributorId"), param.distributorId));
			}

			if (param.success != null) {
				if (param.success)
					list.add(cb.equal(root.get("success"), param.success));
				else
					list.add(cb.or(cb.equal(root.get("success"), false), cb.isNull(root.get("success"))));
			}
			if (CollectionUtils.isNotEmpty(list))
				query.where(cb.and(list.toArray(new Predicate[list.size()])));

			return null;
		};
		return spec;
	}

}
